package com.hse.network;

import com.hse.application.ApplicationLayerException;
import com.hse.application.ApplicationMacStackLayer;
import com.hse.application.MacStackLayerClient;
import com.hse.network.exceptions.NetworkException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Created by IntelliJ IDEA.
 * User: Lexa
 * Date: May 25, 2009
 * Time: 11:10:14 PM
 * To change this template use File | Settings | File Templates.
 */
public class Coordinator implements ICoordinator {
    private static final Log log = LogFactory.getLog(Coordinator.class);

    private enum State {
        Ready,
        Beackoning,
        Stoped
    }

    private ApplicationMacStackLayer mac;
    private State state;
    private Short panId;
    private Long macAddress;

    public Coordinator(String portName, long macAddress) throws InstantiationException {
        this.macAddress = macAddress;
        mac = new ApplicationMacStackLayer(portName);
        try {
            mac.init(macAddress);
        } catch (ApplicationLayerException e) {
            throw new InstantiationException(e.toString());
        }
        state = State.Ready;
    }

    public void close() {
        mac.stop();
        state = State.Stoped;
    }

    public void createNetwork(Short panId) throws NetworkException {
        if (state != State.Ready)
            throw new NetworkException("The coordinator state must be started. Current state is " + state);
        this.panId = panId;
        try {
            mac.init(macAddress);
            mac.createNetwork(this.panId);
        } catch (ApplicationLayerException e) {
            throw new NetworkException(e);
        }
        this.state = State.Beackoning;
    }

    public boolean canAccept() {
        return mac.canAcceptEndDevice();
    }

    public ICoordinatorClient accept() throws NetworkException {
        final MacStackLayerClient macStackLayerClient;
        try {
            macStackLayerClient = mac.acceptEndDevice();
        } catch (ApplicationLayerException e) {
            throw new NetworkException(e);
        }
        return new CoordinatorClient(mac, panId, macStackLayerClient.getShortAddress(),
                ApplicationMacStackLayer.COORDINATOR_SHORT_ADDRESS);
    }

    public void destroyNetwork() throws NetworkException {
        try {
            mac.init(macAddress);
        } catch (ApplicationLayerException e) {
            throw new NetworkException(e);
        }
        state = State.Ready;
    }
}
